package Character;

import org.json.JSONException;
import org.json.JSONObject;

import GameTools.ydLine;
import GameTools.ydMath;
import GameTools.ydPoint;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;

import com.ydDev.charateranimation.R;

public class Arm {

	BodyPart arm, forearm;
	
	ydLine pl1, pl2, pl3, pl4; 

	public Arm(ydPoint position) {
		arm = new BodyPart(position, R.drawable.gc1_arm);
		forearm = new BodyPart(arm.limb.p2, R.drawable.gc1_forearm);

		setJoints();

		ydPoint shift = new ydPoint(arm.j2.x - forearm.j1.x, arm.j2.y
				- forearm.j1.y);
		forearm.deltaMove(shift);
	}
	
	public void setJoints(){
		arm.setFirstJoint(new ydPoint(arm.limb.p1.x, arm.limb.p1.y + 0.173f*arm.skin.getWidth()));
		arm.setSecondJoint(new ydPoint(arm.limb.p1.x, arm.limb.p1.y + 0.827f*arm.skin.getWidth()));

		forearm.setFirstJoint(new ydPoint(forearm.limb.p1.x,
				forearm.limb.p1.y + 0.107f*forearm.skin.getWidth()));
		forearm.setSecondJoint(new ydPoint(forearm.limb.p1.x,
				forearm.limb.p1.y + 0.927f*forearm.skin.getWidth()));
	}

	public void draw(Canvas canvas) {
		arm.draw(canvas);
		forearm.draw(canvas);
		
		//drawParameters(canvas);
	}

	public void rotateArm(double rads, int mode) {
		if (mode == 0) {
			arm.rotate(rads);
			forearm.rotate(rads);

			ydPoint shift = new ydPoint(arm.j2.x - forearm.j1.x, arm.j2.y
					- forearm.j1.y);
			forearm.deltaMove(shift);
		} else if (mode == 1) {
			forearm.rotate(rads);
		}
	}
	
	public void deltaMove(ydPoint shift){
		arm.deltaMove(shift);
		forearm.deltaMove(shift);
	}

	public void pointTo(ydPoint clickedAt) {
		if(ydMath.hypotenuse(arm.j1, clickedAt)>(ydMath.hypotenuse(arm.j1, arm.j2)+ydMath.hypotenuse(forearm.j1, forearm.limb.p2))){
			ydPoint currentSlope=arm.limb.slope;
			ydPoint newSlope=ydMath.slopeOf(arm.j1, clickedAt);
			
			double deltaRads=ydMath.vectorToRads(newSlope)-ydMath.vectorToRads(currentSlope);
			arm.rotate(deltaRads);
			
			ydPoint shift = new ydPoint(arm.j2.x - forearm.j1.x, arm.j2.y
					- forearm.j1.y);
			forearm.deltaMove(shift);
			
			currentSlope=forearm.limb.slope;
			deltaRads=ydMath.vectorToRads(newSlope)-ydMath.vectorToRads(currentSlope);
			forearm.rotate(deltaRads);
		}
		else{
			//ydLine LA=new ydLine(arm.j2, clickedAt);
			ydLine LB=new ydLine(arm.j1, clickedAt);
			//ydLine LC=new ydLine(arm.j1, arm.j2);
			
			double a1 = ydMath.cosineLaw(arm.j2, arm.j1, clickedAt);
			double a2 = ydMath.cosineLaw(clickedAt, arm.j1, arm.j2);

			double a3 = Math.atan2(arm.j2.y - clickedAt.y, arm.j2.x - clickedAt.x);

			double a4 = Math.PI / 2 - a2 - a3;

			double a5 = Math.PI / 2 - a4;

			double a6 = Math.PI - a1 - a5;
			
			System.out.println("A1: " + ydMath.radsToDegrees((float) a1));
			System.out.println("A2: " + ydMath.radsToDegrees((float) a2));
			System.out.println("A3: " + ydMath.radsToDegrees((float) a3));
			System.out.println("A4: " + ydMath.radsToDegrees((float) a4));
			System.out.println("A5: " + ydMath.radsToDegrees((float) a5));
			System.out.println("A6: " + ydMath.radsToDegrees((float) a6));
			System.out.println();
		}
		
	}
	
	public void pointTo(ydPoint clickedAt, int i) {
		if(i==0){
			ydPoint currentSlope=arm.limb.slope;
			ydPoint newSlope=ydMath.slopeOf(arm.j1, clickedAt);
			
			double deltaRads=ydMath.vectorToRads(newSlope)-ydMath.vectorToRads(currentSlope);
			arm.rotate(deltaRads);
			
			ydPoint shift = new ydPoint(arm.j2.x - forearm.j1.x, arm.j2.y
					- forearm.j1.y);
			forearm.deltaMove(shift);
			
			//currentSlope=forearm.limb.slope;
			//deltaRads=ydMath.vectorToRads(newSlope)-ydMath.vectorToRads(currentSlope);
			forearm.rotate(deltaRads);
		}
		else if(i==1){
			ydPoint currentSlope=forearm.limb.slope;
			ydPoint newSlope=ydMath.slopeOf(forearm.j1, clickedAt);
			currentSlope=forearm.limb.slope;
			double deltaRads=ydMath.vectorToRads(newSlope)-ydMath.vectorToRads(currentSlope);
			forearm.rotate(deltaRads);
		}
	}
	
	public void drawParameters(Canvas canvas) {
		Paint p1 = new Paint();
		p1.setColor(Color.RED);
		p1.setTextSize(12);

		ydPoint tl = new ydPoint();
		ydPoint tr = new ydPoint();
		ydPoint bl = new ydPoint();
		ydPoint br = new ydPoint();

		tl.x = Math.min(arm.j1.x, Math.min(arm.j2.x, forearm.j2.x));
		tl.y = Math.min(arm.j1.y, Math.min(arm.j2.y, forearm.j2.y));

		tr.x = Math.max(arm.j1.x, Math.max(arm.j2.x, forearm.j2.x));
		tr.y = Math.min(arm.j1.y, Math.min(arm.j2.y, forearm.j2.y));

		br.x = Math.max(arm.j1.x, Math.max(arm.j2.x, forearm.j2.x));
		br.y = Math.max(arm.j1.y, Math.max(arm.j2.y, forearm.j2.y));

		bl.x = Math.min(arm.j1.x, Math.min(arm.j2.x, forearm.j2.x));
		bl.y = Math.max(arm.j1.y, Math.max(arm.j2.y, forearm.j2.y));
		
		pl1=new ydLine(tl, tr);
		pl2=new ydLine(tl, bl);
		pl3=new ydLine(tr, br);
		pl4=new ydLine(bl, br);
		
		pl1.drawLine(canvas);
		pl2.drawLine(canvas);
		pl3.drawLine(canvas);
		pl4.drawLine(canvas);
		
	}

	public void rotate(int direction) {
		// TODO Auto-generated method stub
		if(direction==0){
		arm.rotate(arm.angularVelocity);
		forearm.rotate(arm.angularVelocity);

		ydPoint shift = new ydPoint(arm.j2.x - forearm.j1.x, arm.j2.y
				- forearm.j1.y);
		forearm.deltaMove(shift);
		}
		else if(direction==1){
			arm.rotate(-arm.angularVelocity);
			forearm.rotate(-arm.angularVelocity);

			ydPoint shift = new ydPoint(arm.j2.x - forearm.j1.x, arm.j2.y
					- forearm.j1.y);
			forearm.deltaMove(shift);
		}
	}

	public JSONObject getJSONArm() throws JSONException {
		JSONObject json=new JSONObject();
		
		json.put("p1", arm.limb.p1.toString());
		json.put("p2", arm.limb.p2.toString());
		json.put("j1", arm.j1.toString());
		json.put("j2", arm.j2.toString());
		json.put("slope", arm.j2.toString());
		return json;
	}

	public JSONObject getJSONForearm() throws JSONException {
		JSONObject json=new JSONObject();
		
		json.put("p1", forearm.limb.p1.toString());
		json.put("p2", forearm.limb.p2.toString());
		json.put("j1", forearm.j1.toString());
		json.put("j2", forearm.j2.toString());
		json.put("slope", forearm.j2.toString());
		return json;
	}

	public void loadPostion(JSONObject json){
		JSONObject jsonArm=new JSONObject();
		JSONObject jsonForearm=new JSONObject();
		try {
			jsonArm=json.getJSONObject("arm");
			jsonForearm=json.getJSONObject("forearm");
		} catch (JSONException e) {
			e.printStackTrace();
		}
		
		arm.limb.setPosition(ydPoint.stringPairToydPoint(jsonArm.optString("p1")), ydPoint.stringPairToydPoint(jsonArm.optString("p2")));
		arm.j1.setCoordinates(ydPoint.stringPairToydPoint(jsonArm.optString("j1")));
		//arm.j2.setCoordinates(ydPoint.stringPairToydPoint(jsonArm.optString("j2")));
		arm.limb.slope.setCoordinates(ydPoint.stringPairToydPoint(jsonArm.optString("slope")));
		arm.recalculateWithSlope();
		
		
		forearm.limb.setPosition(ydPoint.stringPairToydPoint(jsonForearm.optString("p1")), ydPoint.stringPairToydPoint(jsonForearm.optString("p2")));
		forearm.j1.setCoordinates(ydPoint.stringPairToydPoint(jsonForearm.optString("j1")));
		//forearm.j2.setCoordinates(ydPoint.stringPairToydPoint(jsonForearm.optString("j2")));
		forearm.limb.slope.setCoordinates(ydPoint.stringPairToydPoint(jsonArm.optString("slope")));
		forearm.recalculateWithSlope();
		
		setJoints();
		
		
	}

	public void readjust() {
		ydPoint shift = new ydPoint(arm.j2.x - forearm.j1.x, arm.j2.y
				- forearm.j1.y);
		forearm.deltaMove(shift);
		
	}

	public void setScale(float s) {
		arm.setScale(s);
		forearm.setScale(s);
		setJoints();
		
	}

}
